package engine.data;

import java.io.IOException;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import util.ArrayList;
import util.List;
import ai.AIDebug;

public final class UnitType {

	public static final byte NONE = -1;

	public static final byte SETTLER = 0;

	public static final byte DIPLOMAT = 1;

	public static final byte CARAVAN = 2;

	public static final byte ARMOR = 3;

	public static final byte ARTILLERY = 4;

	public static final byte BATTLESHIP = 5;

	public static final byte BOMBER = 6;

	public static final byte CANNON = 7;

	public static final byte CARRIER = 8;

	public static final byte CATAPULT = 9;

	public static final byte CAVALRY = 10;

	public static final byte CHARIOT = 11;

	public static final byte CRUISER = 12;

	public static final byte FIGHTER = 13;

	public static final byte FRIGATE = 14;

	public static final byte IRONCLAD = 15;

	public static final byte KNIGHTS = 16;

	public static final byte LEGION = 17;

	public static final byte MECHANIZED_INFANTRY = 18;

	public static final byte MILITIA = 19;

	public static final byte MUSKETEERS = 20;

	public static final byte NUCLEAR = 21;

	public static final byte PHALANX = 22;

	public static final byte RIFLEMEN = 23;

	public static final byte SAIL = 24;

	public static final byte SUBMARINE = 25;

	public static final byte TRANSPORT = 26;

	public static final byte TRIREME = 27;

	public static final byte CURSOR = 28;

	public static final byte TRIBE = 29;

	public static final byte SIZE = 30;

	public static final String[] NAME = { "Settler", "Diplomat", "Caravan", "Armor", "Artillery", "Battleship",
			"Bomber", "Cannon", "Carrier", "Catapult", "Cavalry", "Chariot", "Cruiser", "Fighter", "Frigate",
			"Ironclad", "Knights", "Legion", "Mech. Inf.", "Militia", "Musketeers", "Nuclear", "Phalanx", "Riflemen",
			"Sail", "Submarine", "Transport", "Trireme", "Cursor", "Tribe" };

	public static final byte[] REQUIRED_TECH = { Technology.NONE, Technology.WRITING, Technology.TRADE,
			Technology.AUTOMOBILE, Technology.ROBOTICS, Technology.STEEL, Technology.ADVANCED_FLIGHT,
			Technology.METALLURGY, Technology.ADVANCED_FLIGHT, Technology.MATHEMATICS, Technology.HORSEBACK_RIDING,
			Technology.THE_WHEEL, Technology.COMBUSTION, Technology.FLIGHT, Technology.MAGNETISM,
			Technology.STEAM_ENGINE, Technology.CHIVALRY, Technology.IRON_WORKING, Technology.LABOR_UNION,
			Technology.NONE, Technology.GUNPOWDER, Technology.ROCKETRY, Technology.BRONZE_WORKING,
			Technology.CONSCRIPTION, Technology.NAVIGATION, Technology.MASS_PRODUCTION, Technology.INDUSTRIALIZATION,
			Technology.MAP_MAKING, Technology.NONE, Technology.NONE };

	public static final byte[] OBSOLETE_BY = { NONE, NONE, NONE, NONE, NONE, NONE, NONE, ARTILLERY, NONE, CANNON,
			MUSKETEERS, KNIGHTS, NONE, NONE, TRANSPORT, CRUISER, ARMOR, MUSKETEERS, NONE, MUSKETEERS, RIFLEMEN, NONE,
			MUSKETEERS, NONE, FRIGATE, NONE, NONE, SAIL, NONE, NONE };

	public static final byte[] AP = { 0, 0, 0, 10, 12, 18, 12, 8, 1, 6, 2, 4, 6, 4, 2, 4, 4, 3, 6, 1, 2, 99, 1, 3, 1,
			8, 1, 1, 0,0 };

	public static final byte[] DP = { 1, 0, 1, 5, 2, 12, 1, 1, 12, 1, 1, 1, 6, 2, 2, 4, 2, 1, 6, 1, 3, 0, 2, 5, 1, 2,
			0, 0, 0,0 };

	public static final byte[] MP = { 1, 2, 1, 3, 2, 4, 8, 1, 5, 1, 2, 2, 6, 10, 3, 4, 2, 1, 3, 1, 1, 16, 1, 1, 3, 3,
			3, 3, 0,0 };

	public static final short[] PP = { 40, 30, 50, 80, 60, 160, 120, 40, 160, 40, 20, 40, 80, 60, 40, 60, 40, 20, 50,
			10, 30, 160, 20, 30, 40, 50, 50, 40,0,0 };

	public static final byte[] RP = { 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
			1,0,0 };

	public static final byte IMAGE_HEIGHT = 15;

	public static final byte IMAGE_WIDTH = 15;

	/**
	 * imageTypes contains all unit's images
	 */
	private static Image[][] imageTypes = new Image[Civilization.SIZE][SIZE];

	private UnitType() {
		// no constructor
	}

	public static Image getImage(final Unit unit) throws IOException {
		byte civId = 0;
		if (unit.player != null)
			civId = unit.player.civilization;
		if (imageTypes[civId][unit.type] == null)
			imageTypes[civId][unit.type] = UnitType.getUnitImageType(unit);
		return imageTypes[civId][unit.type];
	}

	public static boolean isNaval(final Unit unit) {
		return unit.type == BATTLESHIP || unit.type == CARRIER || unit.type == CRUISER || unit.type == FRIGATE
				|| unit.type == IRONCLAD || unit.type == SAIL || unit.type == SUBMARINE || unit.type == TRANSPORT
				|| unit.type == TRIREME;
	}

	public static boolean isAerial(final Unit unit) {
		return unit.type == BOMBER || unit.type == FIGHTER || unit.type == NUCLEAR;
	}

	public static boolean isTerrestrial(final Unit unit) {
		return !isAerial(unit) && !isNaval(unit);
	}

	public static byte getFuelCost(final Unit unit) {
		if (unit.type == FIGHTER || unit.type == NUCLEAR)
			return 1;
		if (unit.type == BOMBER)
			return 2;
		return 0;
	}

	public static byte getTransportCapacity(final Unit unit) {
		if (unit.type == CARRIER || unit.type == TRANSPORT)
			return 8;
		if (unit.type == FRIGATE)
			return 4;
		if (unit.type == SAIL)
			return 3;
		if (unit.type == TRIREME)
			return 2;
		return 0;
	}

	public static byte getUpkeepCostHappy(final Unit unit) {
		if (unit.type == SETTLER || unit.type == DIPLOMAT || unit.type == CARAVAN)
			return 0;
		return 1;
	}

	public static byte getUpkeepCostProduction(final Unit unit) {
		if (unit.type == DIPLOMAT || unit.type == CARAVAN)
			return 0;
		return 1;
	}

	public static byte getUpkeepCostFood(final Unit unit) {
		if (unit.type == SETTLER)
			return 1;
		return 0;
	}

	public static String getName(final short id) {
		return NAME[id];
	}

	public static byte getAP(final byte id) {
		return AP[id];
	}

	public static byte getDP(final byte id) {
		return DP[id];
	}

	public static short getPP(final byte id) {
		return PP[id];
	}

	public static short getMP(final byte id) {
		return MP[id];
	}

	public static byte getRP(final byte id) {
		return RP[id];
	}

	public static List getPossibleUnitTypeIds(final List techs) {
		List ret = new ArrayList();
		//AIDebug.logDebug("size REQUIRED_TECH " + REQUIRED_TECH.length);
		//AIDebug.logDebug("size OBSOLETE_BY " + OBSOLETE_BY.length);
		for (byte i = 0; i < SIZE; i++){
			//AIDebug.logDebug(i + " " + REQUIRED_TECH[i] + " " + OBSOLETE_BY[i]);
			//if (OBSOLETE_BY[i] != NONE) AIDebug.logDebug("=> " + REQUIRED_TECH[OBSOLETE_BY[i]]);
			if ((REQUIRED_TECH[i] == Technology.NONE || techs.contains(new Byte(REQUIRED_TECH[i])))
					&& (OBSOLETE_BY[i] == NONE || !techs.contains(new Byte(REQUIRED_TECH[OBSOLETE_BY[i]]))))
				ret.add(new Byte(i));}
		return ret;
	}

	private static Image getUnitImageType(final Unit unit) throws IOException {
		StringBuffer sb = new StringBuffer();
		if (unit.type == CURSOR) {
			sb.append("/images/unit_");
			sb.append(unit.type);
			sb.append(".png");
			return Image.createImage(sb.toString());
		}
		Image image = Image.createImage(IMAGE_WIDTH, IMAGE_HEIGHT);
		Graphics g = image.getGraphics();
		sb.append("/images/unit_bg_");
		sb.append(unit.player.civilization);
		sb.append(".png");
		Image imgSrc = Image.createImage(sb.toString());
		g.drawImage(imgSrc, 0, 0, Graphics.TOP | Graphics.LEFT);
		sb = new StringBuffer();
		sb.append("/images/unit_");
		sb.append(unit.type);
		sb.append(".png");
		imgSrc = Image.createImage(sb.toString());
		g.drawImage(imgSrc, 0, 0, Graphics.TOP | Graphics.LEFT);
		return image;
	}

}
